﻿Imports Chilkat

Public Class HTTPRequest

    Public Structure HTTPFormValue
        Public Name As String
        Public Value As String
        Public Sub New(_Name As String, Optional _Value As String = "")
            Name = _Name
            Value = _Value
        End Sub
    End Structure

    Private ThisClient As Socket = Nothing
    Private HasContent As Boolean = False

    Public Property ContentLength As Long = 0
    Public Property ContentType As String
    Public Property Content As Byte()
    Public Property Headers As New Net.WebHeaderCollection
    Public Property Method As String
    Public Property URI As String
    Public Property Server As String

    Public Property FormValues As New Hashtable

    Public Sub New(Request As String, Client As Socket)

        If Request = "" Then Exit Sub

        ThisClient = Client
        Dim ThisRequest As String = LTrim(Request)
        Dim RequestParts() As String = ThisRequest.Split(vbCrLf)
        Dim HasURIPostedValues As Boolean = False
        Dim ThisContent As String = ""

        Select Case UCase(RequestParts(0).Split(" ")(0))
            Case "GET"
                Method = "GET"
            Case "HEAD"
                Method = "HEAD"
            Case "POST"
                Method = "POST"
            Case Else
                Debug.Print("Invalid Method '" & UCase(RequestParts(0).Split(" ")(0)) & "'")
                Exit Sub
        End Select
        Debug.Print(Method)

        Dim URIPath As String = RequestParts(0).Split(" ")(1)
        If URIPath.Contains("?") Then
            Dim TempURIPath As String = URIPath
            URIPath = TempURIPath.Split("?")(0)
            HasURIPostedValues = True
            ThisContent = TempURIPath.Split("?")(1)
        End If
        Debug.Print(URIPath)

        ' Read headers
        For i = 1 To UBound(RequestParts)
            Dim ThisHeader As String = RequestParts(i).Replace(vbLf, "").Replace(vbCr, "")
            If Not ThisHeader = "" Then
                Select Case LCase(ThisHeader.Split(":")(0))
                    Case "content-length"
                        ContentLength = CLng(Trim(ThisHeader.Split(":")(1)))
                    Case "content-type"
                        ContentType = Trim(ThisHeader.Split(":")(1))
                    Case "host"
                        Server = Trim(ThisHeader.Split(":")(1))
                    Case "connection"
                    Case "accept"
                    Case "user-agent"
                    Case "pragma"
                    Case "cache-control"
                    Case "content-language"
                    Case Else
                        Debug.Print("Unkbown header '" & ThisHeader.Split(":")(0) & "'")
                End Select
                Headers.Add(ThisHeader)
            Else
                Exit For
            End If
        Next

        URI = Server & URIPath

        ' Read content if available
        If ContentLength > 0 Then
            If ThisClient.PollDataAvailable Then
                Content = ThisClient.ReceiveBytesN(ContentLength)
            Else
                Debug.Print("Expected content, recieved none.")
            End If
        End If

        If LCase(ContentType) = "application/x-www-form-urlencoded" Then
            ThisContent = Text.UTF8Encoding.UTF8.GetString(Content)
        End If

        If LCase(ContentType) = "application/x-www-form-urlencoded" Or HasURIPostedValues Then
            For Each FormValue As String In ThisContent.Split("&").ToList
                Dim ValueParts() As String = FormValue.Split("=")
                If ValueParts.Count = 1 Then
                    FormValues.Add(ValueParts(0), New HTTPFormValue(ValueParts(0)))
                Else
                    FormValues.Add(ValueParts(0), New HTTPFormValue(ValueParts(0), ValueParts(1)))
                End If
            Next
        End If

    End Sub

End Class
